#include "gsyncer.h"
#include "watcher.h"
#include <vector>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <string>
#include <unistd.h>
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <pthread.h>
#include <cstring>
#include <dirent.h>
#include <signal.h>
using namespace std;

void login(string& name, string& pwd, string& main_dir,
			vector<string>& all_path, Watcher& gsyncer);

Watcher *pWatcher=NULL;
/*
void cexit(int sig)
{
    if(pWatcher!=NULL){
		pWatcher->cexit();
    }
    (void)signal(SIGINT,SIG_DFL);
    exit(0);
}
*/
int main(int argc, char *argv[])
{
  //  (void) signal(SIGINT,cexit);
	vector<string> all_path;
	string usr_name,usr_pwd,main_dir;
	main_dir="";
	if(argc==2){
	    main_dir=string(argv[1]);
	}
	printf("%s\n",main_dir.c_str());
	
	Watcher gsyncer;
	cout<<"come here "<<endl;
	login(usr_name,usr_pwd,main_dir,all_path, gsyncer);
	gsyncer.set_usr_info(usr_name,usr_pwd);

	pWatcher = &gsyncer;

	pthread_t tid_process, tid_input;

	//处理事件线程
	if( pthread_create(&tid_process,NULL,process_thread,&gsyncer) < 0 )
	{
		perror("pthread_create");
		exit(-1);
	}

	/*if( pthread_create(&tid_input,NULL,input_thread,&gsyncer) < 0 )
	{
		perror("pthread_create");
		exit(-1);
		}*/
	
	//监控线程
	gsyncer.watch(all_path);
}

void* input_thread(void* gsyncer)
{
	char exit;

	cin >> exit;
	while( exit != 'q' )
	{
		cin >> exit;	
	}

	((Watcher*)gsyncer)->cexit();
}

void login(string& name, string& pwd, string& main_dir, 
			vector<string>& all_path, Watcher& gsyncer)
{
	string pwd_bak;
	char flag;

	if ( connect(gsyncer.ctl_sock,(struct sockaddr*)&gsyncer.srv_ctl, 
				sizeof(gsyncer.srv_ctl)) < 0 )
	{
		perror("connect");
		exit(-1);
	}

	//cout << "a.注册  b.登录"  << endl << ":";
	printf("a.注册   b.登录\n:");
	//cin >> flag;
	scanf("%c",&flag);
	//cout << "请输入用户名:";
	printf("请输入用户名：\n");
	//cin >> name;
	char temname[100];
	scanf("%s",temname);
	name = string(temname);
	if(main_dir==""){
	    get_home(main_dir,name);}
	
	//注册  即第一次使用  不需要同步服务器
	if( flag == 'a' )
	{
		//cout << "请输入密码:";
		//cin >> pwd;
		//cout << "请确认密码:";	
		//cin >> pwd_bak;
		printf("请输入密码：");
		char tempwd[100];
		scanf("%s",tempwd);
		pwd = string(tempwd);
		//＊＊＊＊＊ 核实两次密码＊＊＊＊＊
	
		
		//打包
		struct usr_info info;
		info.type = REG;
		strncpy(info.usr,name.c_str(),USR_LEN-1);
		strncpy(info.pwd,pwd.c_str(),PWD_LEN-1);

		//发送给服务器
		if( writen(gsyncer.ctl_sock,&info,sizeof(struct usr_info)) < 0 )
		{
			perror("write");
			exit(-1);
		}

		//读取服务器的应答
		int8_t reply;
		if( readn(gsyncer.ctl_sock,&reply,sizeof(reply)) < 0 )
		{
			perror("read");
			exit(-1);
		}

		if( reply == -1 )
		{
			//cout << "用户名已经被占用了噢，另外选一个吧" << endl;
			printf("用户名已经被占用了哦，另外选一个吧\n");		
			//		exit(-1);
		}
		
		if( mkdir(main_dir.c_str(),0766) < 0 )
		{
			perror("mkdir");
			//		exit(1);
		}
	
		if( chdir(main_dir.c_str()) < 0 )
		{
			perror("chdir");
			exit(1);
		}
		
		all_path.push_back(main_dir);
		
	} 
	else if (flag == 'b')
	{
		//	cout << "请输入密码:";
		printf("请输入密码\n");
		//cin >> pwd;
		char tempwd[100];
		scanf("%s",tempwd);
		pwd= string(tempwd);
		//打包
		struct usr_info info;
		info.type = LOGIN;
		strncpy(info.usr,name.c_str(),USR_LEN-1);
		strncpy(info.pwd,pwd.c_str(),PWD_LEN-1);

		//发送给服务器
		if( writen(gsyncer.ctl_sock,&info,sizeof(struct usr_info)) < 0 )
		{
			perror("write");
			exit(-1);
		}

		//读取服务器的应答
		int8_t reply;
		if( readn(gsyncer.ctl_sock,&reply,sizeof(reply)) < 0 )
		{
			perror("read");
			exit(-1);
		}

		if( reply != 0 )
		{
		//	cout << "用户名不存在或者密码错误" << endl;
			printf("用户名不存在或者密码错误\n");
			exit(-1);
		}

		if( chdir(main_dir.c_str()) < 0 )
		{
			perror("chdir");
			exit(1);
		}

		//删除本地文件
		//system("rm -r -f *");

		//接收&解压
		int fd_zip;
		if( (fd_zip = open("gsyncer.zip",O_WRONLY|O_CREAT,0766)) < 0 )
		{
			perror("open");
			exit(-1);
		}

		file_rcv(fd_zip,gsyncer.ctl_sock); 
		close(fd_zip);

		system("unzip -q gsyncer.zip ; rm gsyncer.zip");

		//找出所有文件夹，存入all_path
		all_path.push_back(main_dir);
		dir_search(all_path,main_dir);
	}
}

void get_home(string& dir, string& name)
{
	dir = "/home/";
	dir +=  getlogin();
	dir += "/gsyncer/";
	dir += name;
}

void* process_thread(void* gsyncer)
{
	((Watcher*)gsyncer)->process_events();
}

void dir_search(vector<string>& watch_list, string& pre_path)
{
	DIR * pre;

	if( (pre = opendir(pre_path.c_str())) == NULL )
	{
		perror("opdir");
		exit(-1);
	}

	struct dirent *guy = readdir(pre);
	struct stat file_info;

	while( guy != NULL )
	{
		if( strcmp(guy->d_name,".") == 0 || strcmp(guy->d_name,"..") == 0 )
		{
			guy = readdir(pre);
			continue;
		}

		string name_temp = pre_path + "/";
		name_temp += guy->d_name;

		if( stat(name_temp.c_str(),&file_info) < 0 )
		{
			perror("stat");
			exit(-1);
		}

		if( S_ISDIR(file_info.st_mode) )
		{
			watch_list.push_back(name_temp);
			dir_search(watch_list,name_temp);
		}

		guy = readdir(pre);
	}
}
